package cn.bugstack.ai.service;

import cn.bugstack.ai.model.TraceRecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 溯源服务
 * 记录和管理 AI 调用的溯源信息
 * 
 * @author bugstack
 */
@Slf4j
@Service
public class TracingService {
    
    /**
     * 存储溯源记录
     * Key: traceId, Value: 溯源步骤列表
     */
    private final ConcurrentHashMap<String, List<TraceRecord>> traceRecords = new ConcurrentHashMap<>();
    
    /**
     * 创建溯源ID
     */
    public String createTraceId() {
        String traceId = "trace_" + System.currentTimeMillis() + "_" + 
                UUID.randomUUID().toString().substring(0, 8);
        log.debug("🆔 Created trace ID: {}", traceId);
        return traceId;
    }
    
    /**
     * 记录溯源步骤
     */
    public void recordStep(String traceId, Integer stepId, String action,
                          String description, String input, String output) {
        recordStep(traceId, stepId, action, description, input, output, null);
    }
    
    /**
     * 记录溯源步骤（带时长）
     */
    public void recordStep(String traceId, Integer stepId, String action,
                          String description, String input, String output, Long duration) {
        TraceRecord record = TraceRecord.builder()
                .traceId(traceId)
                .stepId(stepId)
                .timestamp(LocalDateTime.now())
                .action(action)
                .description(description)
                .input(TraceRecord.TraceInput.builder()
                        .prompt(input)
                        .build())
                .output(TraceRecord.TraceOutput.builder()
                        .content(output)
                        .build())
                .duration(duration)
                .status("success")
                .build();
        
        traceRecords.computeIfAbsent(traceId, k -> Collections.synchronizedList(new ArrayList<>()))
                .add(record);
        
        log.debug("📝 Trace step recorded - TraceId: {}, StepId: {}, Action: {}", 
                traceId, stepId, action);
    }
    
    /**
     * 记录溯源步骤（完整信息）
     */
    public void recordStep(TraceRecord record) {
        traceRecords.computeIfAbsent(record.getTraceId(), 
                k -> Collections.synchronizedList(new ArrayList<>()))
                .add(record);
        
        log.debug("📝 Trace step recorded - TraceId: {}, StepId: {}, Action: {}", 
                record.getTraceId(), record.getStepId(), record.getAction());
    }
    
    /**
     * 获取溯源记录
     */
    public List<TraceRecord> getTraceRecords(String traceId) {
        return traceRecords.getOrDefault(traceId, new ArrayList<>());
    }
    
    /**
     * 获取特定步骤
     */
    public TraceRecord getStep(String traceId, Integer stepId) {
        return getTraceRecords(traceId).stream()
                .filter(record -> record.getStepId().equals(stepId))
                .findFirst()
                .orElse(null);
    }
    
    /**
     * 检查溯源是否存在
     */
    public boolean hasTrace(String traceId) {
        return traceRecords.containsKey(traceId);
    }
    
    /**
     * 获取溯源步骤数量
     */
    public int getStepCount(String traceId) {
        return getTraceRecords(traceId).size();
    }
    
    /**
     * 清理溯源记录
     */
    public void clearTrace(String traceId) {
        traceRecords.remove(traceId);
        log.info("🗑️ Trace cleared - TraceId: {}", traceId);
    }
    
    /**
     * 清理所有过期的溯源记录
     * 保留最近1小时的记录
     */
    public void cleanOldTraces() {
        LocalDateTime cutoffTime = LocalDateTime.now().minusHours(1);
        traceRecords.entrySet().removeIf(entry -> {
            List<TraceRecord> records = entry.getValue();
            if (records.isEmpty()) {
                return true;
            }
            LocalDateTime lastTimestamp = records.get(records.size() - 1).getTimestamp();
            return lastTimestamp.isBefore(cutoffTime);
        });
        log.info("🧹 Cleaned old traces, Remaining: {}", traceRecords.size());
    }
    
    /**
     * 获取溯源总结
     */
    public Map<String, Object> getTraceSummary(String traceId) {
        List<TraceRecord> records = getTraceRecords(traceId);
        
        Map<String, Object> summary = new HashMap<>();
        summary.put("traceId", traceId);
        summary.put("totalSteps", records.size());
        summary.put("startTime", records.isEmpty() ? null : records.get(0).getTimestamp());
        summary.put("endTime", records.isEmpty() ? null : records.get(records.size() - 1).getTimestamp());
        
        long totalDuration = records.stream()
                .filter(r -> r.getDuration() != null)
                .mapToLong(TraceRecord::getDuration)
                .sum();
        summary.put("totalDuration", totalDuration);
        
        return summary;
    }
}
